package rs.fon.is.music.services.rest;

import java.util.LinkedList;
import java.util.List;

import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

import com.google.gson.JsonArray;
import com.google.gson.JsonObject;

import rs.fon.is.music.domain.MusicAlbum;
import rs.fon.is.music.domain.MusicGroup;
import rs.fon.is.music.domain.MusicRecording;
import rs.fon.is.music.services.MusicService;
import rs.fon.is.music.services.MusicServiceImpl;
import rs.fon.is.music.services.rest.parsers.MusicAlbumJsonParser;
import rs.fon.is.music.services.rest.parsers.MusicGroupJsonParser;
import rs.fon.is.music.services.rest.parsers.MusicRecordingJsonParser;

@Path("/groups")
public class MusicGroupRestService {

	private MusicService musicRepository;

	public MusicGroupRestService() {
		musicRepository = new MusicServiceImpl();
	}

	@GET
	@Produces(MediaType.APPLICATION_JSON)
	public String getMusicGroups(
			@DefaultValue("-1") @QueryParam("limit") int limit,
			@DefaultValue("-1") @QueryParam("offset") int offset,
			@DefaultValue("-1") @QueryParam("minFoundingYear") int minFoundingYear,
			@DefaultValue("-1") @QueryParam("maxFoundingYear") int maxFoundingYear,
			@DefaultValue("-1") @QueryParam("minAlbums") long minAlbums,
			@DefaultValue("-1") @QueryParam("maxAlbums") long maxAlbums,
			@DefaultValue("-1") @QueryParam("minTracks") long minTracks,
			@DefaultValue("-1") @QueryParam("maxTracks") long maxTracks,
			@DefaultValue("-1") @QueryParam("interactionCount") long interactionCount,
			@DefaultValue("") @QueryParam("tags") String tags) {

		LinkedList<String> tagsList = new LinkedList<>();
		if (!tags.isEmpty()) {
			String[] tagsArray = tags.split(",");
			for (int i = 0; i < tagsArray.length; i++) {
				tagsList.add(tagsArray[i]);
			}
		}

		List<MusicGroup> groups = musicRepository.getMusicGroups(limit, offset,
				minFoundingYear, maxFoundingYear, minAlbums, maxAlbums,
				minTracks, maxTracks, interactionCount, tagsList);

		if (groups != null && !groups.isEmpty()) {
			JsonArray groupsArray = new JsonArray();

			for (MusicGroup group : groups) {
				JsonObject groupJson = MusicGroupJsonParser.serialize(group);
				groupsArray.add(groupJson);
			}
			return groupsArray.toString();
		}

		throw new WebApplicationException(Response.Status.NO_CONTENT);
	}

	@GET
	@Path("{id}")
	@Produces(MediaType.APPLICATION_JSON)
	public String getMusicGroup(@PathParam("id") String id) {
		MusicGroup group = musicRepository.getMusicGroup(id);

		if (group != null) {
			JsonObject groupJson = MusicGroupJsonParser.serialize(group);
			return groupJson.toString();
		}

		throw new WebApplicationException(Response.Status.NO_CONTENT);
	}

	@GET
	@Path("{id}/albums")
	@Produces(MediaType.APPLICATION_JSON)
	public String getAlbums(
			@PathParam("id") String groupID,
			@DefaultValue("-1") @QueryParam("limit") int limit,
			@DefaultValue("-1") @QueryParam("offset") int offset,
			@DefaultValue("-1") @QueryParam("minTracks") long minTracks,
			@DefaultValue("-1") @QueryParam("maxTracks") long maxTracks,
			@DefaultValue("-1") @QueryParam("interactionCount") long interactionCount,
			@DefaultValue("") @QueryParam("tags") String tags) {

		LinkedList<String> tagsList = new LinkedList<>();
		if (!tags.isEmpty()) {
			String[] tagsArray = tags.split(",");
			for (int i = 0; i < tagsArray.length; i++) {
				tagsList.add(tagsArray[i]);
			}
		}

		List<MusicAlbum> albums = musicRepository.getAlbums(groupID, limit,
				offset, minTracks, maxTracks, interactionCount, tagsList);

		if (albums != null && !albums.isEmpty()) {
			JsonArray albumsArray = new JsonArray();

			for (MusicAlbum album : albums) {
				JsonObject albumJson = MusicAlbumJsonParser.serialize(album);
				albumsArray.add(albumJson);
			}
			return albumsArray.toString();
		}

		throw new WebApplicationException(Response.Status.NO_CONTENT);
	}

	@GET
	@Path("{id}/recordings")
	@Produces(MediaType.APPLICATION_JSON)
	public String getRecordings(
			@PathParam("id") String groupID,
			@DefaultValue("-1") @QueryParam("limit") int limit,
			@DefaultValue("-1") @QueryParam("offset") int offset,
			@DefaultValue("-1") @QueryParam("interactionCount") long interactionCount,
			@DefaultValue("") @QueryParam("tags") String tags) {

		LinkedList<String> tagsList = new LinkedList<>();
		if (!tags.isEmpty()) {
			String[] tagsArray = tags.split(",");
			for (int i = 0; i < tagsArray.length; i++) {
				tagsList.add(tagsArray[i]);
			}
		}

		List<MusicRecording> recordings = musicRepository.getRecordings(
				groupID, limit, offset, interactionCount, tagsList);

		if (recordings != null && !recordings.isEmpty()) {
			JsonArray recordingsArray = new JsonArray();
			for (MusicRecording recording : recordings) {
				JsonObject recordingJson = MusicRecordingJsonParser.serialize(recording);
				recordingsArray.add(recordingJson);
			}
			return recordingsArray.toString();
		}

		throw new WebApplicationException(Response.Status.NO_CONTENT);
	}
}
